﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sealight.Core.Domain;
using Sealight.API.Framework;
using Sealight.Data;
using Sealight.API.Ioc;
using NHibernate;
using NHibernate.Collection;
using Sealight.Core.DataAdapter;

namespace Sealight.CoreAPI
{
    public class ProductService : IProductService
    {
        public IList<product> GetAllProducts()
        {
            IList<ProductEntity> listData = null;
            IList<product> list = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();
                listData = repo.GetAll();

                if (listData != null)
                    list = (from c in listData orderby c.ModifiedDate descending select c.ToDataAdapter()).ToList();
            }
            catch (Exception ex)
            {
                throw new Exception("Error get products data. ErrMsg: " + ex.Message, ex);
            }
            return list;
        }

        public product AddOrUpdate(product item)
        {
            if (item == null)
                throw new ArgumentNullException("item data is Null.");
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }
            bool addNew = false;
            try
            {
                ProductEntity data = null;
                IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();
                IRepository<ProductTypeEntity> repoPT = IocContainer.Container().Resolve<IRepository<ProductTypeEntity>>();
                
                if (item.id != Guid.Empty)
                    data = repo.GetById(item.id);
                if (data == null)
                {
                    addNew = true;
                    data = new ProductEntity();
                }
                //Save Product
                data.Name = item.name;
                data.MetaTitle = item.metaTitle;
                data.MetaDescription = item.meta_description;
                data.MetaKeywords = item.meta_keywords;
                data.FullDescription = item.full_description;
                data.ShortDescription = item.short_description;
                data.SEName = item.se_name;
                data.ShowOnHomePage = item.show_on_home_page;
                data.AllowRatings = item.allow_ratings;
                data.AllowReviews = item.allow_reviews;
                data.CreatedDate = item.created_date;
                data.ModifiedDate = item.modified_date;
                data.Published = item.published;
                data.Deleted = item.deleted;

                data.ProductType = repoPT.GetById(item.type.id);

                //Add Update Category
                repo.SaveOrUpdate(data);

                if (addNew && item.base_variant != null)
                {
                    product_variant variant = item.base_variant;
                    variant.product_id = data.ProductID;
                    variant.created_date = DateTime.Now;
                    variant.modified_date = DateTime.Now;

                    this.AddOrUpdateProductVariant(variant);
                }

                if (commitTrans)
                    uow.TransactionalFlush();

                item = data.ToDataAdapter();

            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error saving product data. ErrMsg: " + ex.Message, ex);
            }

            return item;
        }

        public IList<product_category_map> MapCategoryToProduct(IList<product_category_map> category, Guid id)
        {
            IList<product_category_map> entity = null;
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                ProductEntity data = null;
                IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();  

                data = repo.GetById(id);

                if (data != null)
                {
                    //Add Update Category
                    //data.CategoryMaps = null;
                    foreach (product_category_map cat in category)
                    {
                        ProductCategoryEntity mapCategory = null;
                        if (cat.category.id != Guid.Empty)
                        {
                            CategoryEntity productCategory = repo.GetProductCategoryByID(cat.category.id);
                            mapCategory = new ProductCategoryEntity
                            {
                                DisplayOrder = cat.display_order,
                                IsFeaturedProduct = cat.is_featured_product,
                                Category = productCategory,
                                Product = data
                            };
                            repo.MapCategoryToProduct(mapCategory);
                        }
                    } 

                    if (commitTrans)
                        uow.TransactionalFlush();

                    data = repo.GetById(id);

                    if (data.CategoryMaps != null)
                        entity = (from c in data.CategoryMaps orderby c.DisplayOrder ascending select c.ToDataAdapter()).ToList();
                }

                return entity;
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error saving product data. ErrMsg: " + ex.Message, ex);
            }
        }
        public product_category AddOrUpdateCategory(product_category item)
        {
             if (item == null)
                throw new ArgumentNullException("category data is Null.");
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IProductDataRepository repoP = IocContainer.Container().Resolve<IProductDataRepository>();
                IRepository<CategoryEntity> repo = IocContainer.Container().Resolve<IRepository<CategoryEntity>>();
                IRepository<PictureEntity> repoPic = IocContainer.Container().Resolve<IRepository<PictureEntity>>();
                CategoryEntity data = repo.GetById(item.id);

                if (data == null)
                {
                    
                    data = new CategoryEntity();
                    data.CreatedDate = DateTime.Now;
                }

                data.Name = item.name;
                data.SEName = item.se_name;
                data.PageSize = item.page_size;
                data.Description = item.description;
                data.DisplayOrder = item.display_order;                
                data.ModifiedDate = DateTime.Now;
                data.MetaTitle = item.meta_title;
                data.MetaKeywords = item.meta_keywords;
                data.MetaDescription = item.meta_description;
                data.PriceRanges = item.price_ranges;
                data.ParentID = item.parent_id;
                
                if (item.picture != null && !string.IsNullOrEmpty( item.picture.picture_url))
                {
                    PictureEntity pic = repoPic.GetById(item.picture.id);
                    if (pic == null)
                        pic = new PictureEntity();
                    pic.PictureURL = item.picture.picture_url;
                    pic.Order = item.picture.order;

                    repoP.AddPicture(pic);

                    data.Picture = pic;
                }
                repo.SaveOrUpdate(data);
                if (commitTrans)
                    uow.TransactionalFlush();

                item = data.ToDataAdapter();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error saving product data. ErrMsg: " + ex.Message, ex);
            }

            return item;
        }
        public picture AddPictureToProduct(picture pic, Guid pro_id)
        {
            if (pic == null)
                throw new ArgumentNullException("pic data is Null.");
            if (pro_id == Guid.Empty)
                throw new ArgumentNullException("pro_id is Null.");

            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                
                IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();
                ProductEntity p = repo.GetById(pro_id);
                PictureEntity data = null;

                if (pic.id != Guid.Empty)
                    data = repo.GetPictureByID(pic.id);

                if (data == null)
                    data = new PictureEntity();

                data.Order = pic.order;
                data.Name = pic.name;
                data.PictureURL = pic.picture_url;
                data.Extension = pic.extension;

                /*if (p != null)
                {
                    if (data.Product == null) data.Product = new List<ProductEntity>();

                    data.Product.Add(p);

                }*/

                repo.AddPicture(data);

                if(p!= null)
                {
                    if (p.Pictures == null) p.Pictures = new List<PictureEntity>();
                    p.Pictures.Add(data);

                    repo.SaveOrUpdate(p);
                }

                if (commitTrans)
                    uow.TransactionalFlush();

                pic = data.ToDataAdapter();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error saving product data. ErrMsg: " + ex.Message, ex);
            }

            return pic;
        }

        public product_variant AddOrUpdateProductVariant(product_variant item)
        {
            if (item == null)
                throw new ArgumentNullException("item data is Null.");
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                ProductVariantEntity data = null;
                IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();

                if (item.id != Guid.Empty)
                    data = repo.GetProductVariantByID(item.id);
                if (data == null)
                {                    
                    data = new ProductVariantEntity();
                    data.CreatedDate = item.created_date;
                }
                //Save Product
                data.Name = item.name;
                data.Description = item.description;
                data.Height = item.height;
                data.Length = item.length;
                data.OldPrice = item.old_price;
                data.Price = item.price;
                data.ProductCost = item.product_cost;
                data.SKU = item.SKU;
                data.StockQuantity = item.stock_quantity;
                data.MinStockQuantity = item.min_stock_quantity;
                data.OrderMaximumQuantity = item.order_maximum_quantity;
                data.Weight = item.weight;
                data.Width = item.width;
                data.AvailableStartDateTime = item.available_start_date_time;
                data.AvailableEndDateTime = item.available_end_date_time;
                data.DisplayStockAvailability = item.display_stock_availability;

                
                data.ModifiedDate = item.modified_date;

                data.Product = repo.GetById(item.product_id);
                if (item.picture != null && !string.IsNullOrEmpty(item.picture.picture_url))
                {
                     IRepository<PictureEntity> repoPic = IocContainer.Container().Resolve<IRepository<PictureEntity>>();

                     PictureEntity image = repoPic.GetById(item.picture.id);
                     if (image == null)
                         image = new PictureEntity();

                     image.PictureURL = item.picture.picture_url;
                     image.Name = item.picture.name;

                     repoPic.SaveOrUpdate(image);
                     data.Picture = image;
                }
                repo.SaveOrUpdateProductVariant(data);
                if (commitTrans)
                    uow.TransactionalFlush();

                item = data.ToDataAdapter();

            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error saving product data. ErrMsg: " + ex.Message, ex);
            }

            return item;
        }

        public product GetProductByID(Guid id)
        {
            product entity = null;
            if (id == Guid.Empty)
                throw new ArgumentNullException("Product ID cannot be NULL.");
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();
                ProductEntity data = repo.GetById(id);

                if (data != null)
                    entity = data.ToDataAdapter();
            }
            catch (Exception ex)
            {
                throw new Exception("Get Product by ID Error::" + ex.Message, ex);
            }

            return entity;
        }

        public product_variant GetProductVariantByID(Guid id)
        {
            product_variant entity = null;
            if (id == Guid.Empty)
                throw new ArgumentNullException("Product ID cannot be NULL.");
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();
                ProductVariantEntity data = repo.GetProductVariantByID(id);

                if (data != null)
                    entity = data.ToDataAdapter();
            }
            catch (Exception ex)
            {
                throw new Exception("Get Product by ID Error::" + ex.Message, ex);
            }

            return entity;
        }

        public void AddPictureToProductVariant(Guid picture_id, Guid product_variant_id)
        {
            if (picture_id == Guid.Empty)
                throw new ArgumentNullException("picture_id is Null.");
            if (product_variant_id == Guid.Empty)
                throw new ArgumentNullException("product_variant_id is Null.");
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                ProductVariantEntity data = null;
                IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();
                PictureEntity p = repo.GetPictureByID(picture_id);

                data = repo.GetProductVariantByID(product_variant_id);

                data.Picture = p;

                repo.SaveOrUpdateProductVariant(data);

                if (commitTrans)
                    uow.TransactionalFlush();

            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error saving product data. ErrMsg: " + ex.Message, ex);
            }
        }

        public void RemovePictureFromProduct(IList<Guid> picture_id, Guid productId)
        {
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }
            foreach (Guid img in picture_id)
            {
                RemovePictureFromProduct(img, productId);
            }
            if (commitTrans)
                uow.TransactionalFlush();
        }

        public void RemovePictureFromProduct(Guid picture_id, Guid productId)
        {
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();
            PictureEntity p = repo.GetPictureByID(picture_id);
            ProductEntity data = repo.GetById(productId);
            if (p.Product == null || p.Product.Count == 0 || (p.Product.Count == 1 && p.Product[0].ProductID == productId))
            {
                data.Pictures.Remove(p);
                repo.DeletePicture(p);
            }
            else
            {
                data.Pictures.Remove(p);
            }

            if (commitTrans)
                uow.TransactionalFlush();
        }

        public void Delete(product item)
        {
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();
                ProductEntity data = repo.GetById(item.id);
                repo.Delete(data);

                if (commitTrans)
                    uow.TransactionalFlush();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error delete Product item. ErrMsg: " + ex.Message, ex);
            }
        }

        public product_review AddReview(product_review item)
        {
            if (item == null)
                throw new ArgumentNullException("item data is Null.");
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }
            try
            {
                IRepository<ProductReviewEntity> repo = IocContainer.Container().Resolve<IRepository<ProductReviewEntity>>();
                IProductDataRepository repoP = IocContainer.Container().Resolve<IProductDataRepository>();
                IUserRepository repoU = IocContainer.Container().Resolve<IUserRepository>();
                ProductReviewEntity data = repo.GetById(item.id);
                
                if (data == null)
                    data = new ProductReviewEntity();

                data.ReviewText = item.review_text;
                data.Title = item.title;
                data.IsApproved = item.is_approved;
                data.Rating = item.rating;
                data.CreatedDate = DateTime.Now;
                data.HelpfulNoTotal = item.helpful_no_total;
                data.HelpfulYesTotal = item.helpful_yes_total;

                if (item.product != null)
                    data.Product = repoP.GetById(item.product.id);
                if (item.user != null)
                    data.User = repoU.GetById(item.user.id);
                repo.SaveOrUpdate(data);

                if (commitTrans)
                    uow.TransactionalFlush();

                item = data.ToDataAdapter();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error AddReview data. ErrMsg: " + ex.Message, ex);
            }

            return item;
        }

        public product_rating AddRating(product_rating item)
        {
            if (item == null)
                throw new ArgumentNullException("item data is Null.");
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IRepository<ProductRatingEntity> repo = IocContainer.Container().Resolve<IRepository<ProductRatingEntity>>();
                IProductDataRepository repoP = IocContainer.Container().Resolve<IProductDataRepository>();
                IUserRepository repoU = IocContainer.Container().Resolve<IUserRepository>();

                ProductRatingEntity data = repo.GetById(item.id);               

                if(data== null)
                data=new ProductRatingEntity();
                data.Rating = item.rating;
                data.RatedOn = item.rating_on;

                if (item.product != null)
                    data.Product = repoP.GetById(item.product.id);
                if (item.user != null)
                    data.User = repoU.GetById(item.user.id);

                repo.SaveOrUpdate(data);
                if (commitTrans)
                    uow.TransactionalFlush();

                item = data.ToDataAdapter();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error AddRating data. ErrMsg: " + ex.Message, ex);
            }
            return item;
        }

        public product_attribute AddProductAttribute(product_attribute item)
        {
            if (item == null)
                throw new ArgumentNullException("item data is Null.");
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IRepository<ProductAttributeEntity> repo = IocContainer.Container().Resolve<IRepository<ProductAttributeEntity>>();

                ProductAttributeEntity data = repo.GetById(item.id);
                
                if (data == null)
                    data = new ProductAttributeEntity();
                data.Name = item.name;
                data.Description = item.description;

                repo.SaveOrUpdate(data);
                if (commitTrans)
                    uow.TransactionalFlush();
                item = data.ToDataAdapter();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error AddProductAttribute data. ErrMsg: " + ex.Message, ex);
            }
            return item;
        }

        public product_variant_attribute AddProductVariantAttribute(product_variant_attribute item)
        {
            if (item == null)
                throw new ArgumentNullException("item data is Null.");
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }
            try
            {
                IRepository<ProductVariantAttributeEntity> repo = IocContainer.Container().Resolve<IRepository<ProductVariantAttributeEntity>>();
                IProductDataRepository repoP = IocContainer.Container().Resolve<IProductDataRepository>();
                IRepository<ProductAttributeEntity> repoA = IocContainer.Container().Resolve<IRepository<ProductAttributeEntity>>();

                ProductVariantAttributeEntity data = repo.GetById(item.id);

                if (data == null)
                    data = new ProductVariantAttributeEntity();
                data.AttributeControlType = item.attribute_control_type;
                data.DisplayOrder = item.display_order;
                data.IsRequired = item.is_required;
                data.TextPrompt = item.text_prompt;

                if (item.product_attribute != null)
                    data.ProductAttribute = repoA.GetById(item.product_attribute.id);
                if (item.product_variant != null)
                    data.ProductVariant = repoP.GetProductVariantByID(item.product_variant.id);

                repo.SaveOrUpdate(data);
                if (commitTrans)
                    uow.TransactionalFlush();

                item = data.ToDataAdapter();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error AddProductVariantAttribute data. ErrMsg: " + ex.Message, ex);
            }
            return item;
        }

        public product_variant_attribute_value AddProductVariantAttributeValue(product_variant_attribute_value item)
        {
            if (item == null)
                throw new ArgumentNullException("item data is Null.");
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IRepository<ProductVariantAttributeEntity> repo = IocContainer.Container().Resolve<IRepository<ProductVariantAttributeEntity>>();
                IRepository<ProductVariantAttributeValueEntity> repoV = IocContainer.Container().Resolve<IRepository<ProductVariantAttributeValueEntity>>();

                ProductVariantAttributeValueEntity data = repoV.GetById(item.id);
                if (data == null)
                    data = new ProductVariantAttributeValueEntity();
                data.DisplayOrder = item.display_order;
                data.Name = item.name;
                data.PriceAdjustment = item.price_adjustment;
                data.IsPreSelected = item.is_pre_selected;
                data.WeightAdjustment = item.weight_adjustment;

                data.ProductVariantAttribute = repo.GetById(item.product_variant_attribute_id);

                repoV.SaveOrUpdate(data);
                if (commitTrans)
                    uow.TransactionalFlush();
                item = data.ToDataAdapter();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error AddProductVariantAttributeValue data. ErrMsg: " + ex.Message, ex);
            }

            return item;
        }

        public specification_attribute AddSpecificationAttribute(specification_attribute item)
        {
            if (item == null)
                throw new ArgumentNullException("item data is Null.");
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IRepository<SpecificationAttributeEntity> repo = IocContainer.Container().Resolve<IRepository<SpecificationAttributeEntity>>();
                IProductDataRepository repoP = IocContainer.Container().Resolve<IProductDataRepository>();

                SpecificationAttributeEntity data = repo.GetById(item.id);
                if (data == null)
                    data = new SpecificationAttributeEntity();

                data.DisplayOrder = item.display_order;
                data.Name = item.name;
                data.Category = repoP.GetProductCategoryByID(item.CategoryId);

                repo.SaveOrUpdate(data);
                if (commitTrans)
                    uow.TransactionalFlush();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error AddSpecificationAttribute data. ErrMsg: " + ex.Message, ex);
            }

            return item;
        }

        public specification_attribute_option AddSpecificationAttributeOption(specification_attribute_option item)
        {
            if (item == null)
                throw new ArgumentNullException("item data is Null.");
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IRepository<SpecificationAttributeOptionEntity> repoOP = IocContainer.Container().Resolve<IRepository<SpecificationAttributeOptionEntity>>();
                IRepository<SpecificationAttributeEntity> repo = IocContainer.Container().Resolve<IRepository<SpecificationAttributeEntity>>();

                SpecificationAttributeOptionEntity data = repoOP.GetById(item.id);
                if (data == null)
                    data = new SpecificationAttributeOptionEntity();
                data.DisplayOrder = item.display_order;
                data.Name = item.name;

                if (item.specification_attribute != null)
                {
                    data.SpecificationAttribute = repo.GetById(item.specification_attribute.id);
                }

                repoOP.SaveOrUpdate(data);
                if (commitTrans)
                    uow.TransactionalFlush();
                item = data.ToDataAdapter();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error AddSpecificationAttributeOption data. ErrMsg: " + ex.Message, ex);
            }

            return item;
        }

        public product_specification_attribute MapProductSpecificationAttribute(product_specification_attribute item)
        {
            if (item == null)
                throw new ArgumentNullException("item data is Null.");
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IRepository<SpecificationAttributeOptionEntity> repoOP = IocContainer.Container().Resolve<IRepository<SpecificationAttributeOptionEntity>>();
                IProductDataRepository repoP = IocContainer.Container().Resolve<IProductDataRepository>();
                IRepository<ProductSpecificationAttributeEntity> repoPA = IocContainer.Container().Resolve<IRepository<ProductSpecificationAttributeEntity>>();

                ProductSpecificationAttributeEntity data = repoPA.GetById(item.id);
                if (data == null)
                    data = new ProductSpecificationAttributeEntity();

                data.AllowFiltering = item.allow_filtering;
                data.DisplayOrder = item.display_order;
                data.ShowOnProductPage = item.show_on_product_page;

                if (item.option != null)
                    data.Option = repoOP.GetById(item.option.id);
                if (item.product != null)
                    data.Product = repoP.GetById(item.product.id);

                repoPA.SaveOrUpdate(data);
                if (commitTrans)
                    uow.TransactionalFlush();

                item = data.ToDataAdapter();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error MapProductSpecificationAttribute data. ErrMsg: " + ex.Message, ex);
            }
            return item;
        }

        public IList<product_attribute> GetAllProductAttribute()
        {
            IList<product_attribute> data = null;           
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                IRepository<ProductAttributeEntity> repo = IocContainer.Container().Resolve <IRepository<ProductAttributeEntity>>();
                var result = repo.GetAll();
                if (result != null)
                    data = (from c in result select c.ToDataAdapter()).ToList();
            }
            catch (Exception ex)
            {
                throw new Exception("Get Product by ID Error::" + ex.Message, ex);
            }

            return data;
        }

        public product_attribute GetProductAttribute(Guid id)
        {
            product_attribute data = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                IRepository<ProductAttributeEntity> repo = IocContainer.Container().Resolve<IRepository<ProductAttributeEntity>>();
                var result = repo.GetById(id);
                if (result != null)
                    data = result.ToDataAdapter();
            }
            catch (Exception ex)
            {
                throw new Exception("Get Product by ID Error::" + ex.Message, ex);
            }

            return data;
        }
        public void DeleteProductAttribute(Guid id)
        {
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IRepository<ProductAttributeEntity> repo = IocContainer.Container().Resolve<IRepository<ProductAttributeEntity>>();
                var result = repo.GetById(id);
                repo.Delete(result);
                if (commitTrans)
                    uow.TransactionalFlush();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error delete Product Attribute item. ErrMsg: " + ex.Message, ex);
            }
        }
        public IList<product_category> GetAllCategoryByParentId(Guid parentId)
        {
            IList<product_category> data = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();
                var result = repo.GetCategoryByParentID(parentId);
                if (result != null)
                    data = (from c in result orderby c.DisplayOrder ascending select c.ToDataAdapter()).ToList();
            }
            catch (Exception ex)
            {
                throw new Exception("Get Product by ID Error::" + ex.Message, ex);
            }

            return data;
        }
        public IList<specification_attribute> GetAllSpecificationProductAttribute()
        {
            IList<specification_attribute> data = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                IRepository<SpecificationAttributeEntity> repo = IocContainer.Container().Resolve<IRepository<SpecificationAttributeEntity>>();
                var result = repo.GetAll();
                if (result != null)
                    data = (from c in result orderby c.DisplayOrder ascending select c.ToDataAdapter()).ToList();
            }
            catch (Exception ex)
            {
                throw new Exception("Get Product by ID Error::" + ex.Message, ex);
            }

            return data;
        }
        public IList<product_category> GetAllCategory()
        {
            IList<product_category> data = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                IRepository<CategoryEntity> repo = IocContainer.Container().Resolve<IRepository<CategoryEntity>>();
                var result = repo.GetAll();
                if (result != null)
                    data = (from c in result where !c.ParentID.HasValue orderby c.DisplayOrder ascending select c.ToDataAdapter()).ToList();
            }
            catch (Exception ex)
            {
                throw new Exception("Get GetAllCategory by ID Error::" + ex.Message, ex);
            }

            return data;
        }
        public void DeleteSpecificationAttribute(Guid id)
        {
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IRepository<SpecificationAttributeEntity> repo = IocContainer.Container().Resolve<IRepository<SpecificationAttributeEntity>>();
                var result = repo.GetById(id);
                repo.Delete(result);
                if (commitTrans)
                    uow.TransactionalFlush();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error delete Specification Attribute item. ErrMsg: " + ex.Message, ex);
            }
        }
        public IList<specification_attribute_option> GetAllOptionBySpecificationId(Guid id)
        {
            IList<specification_attribute_option> data = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();
                var result = repo.GetAllOptionBySpecificationId(id);
                if (result != null)
                    data = (from c in result orderby c.DisplayOrder ascending select c.ToDataAdapter()).ToList();
            }
            catch (Exception ex)
            {
                throw new Exception("Get Product by ID Error::" + ex.Message, ex);
            }

            return data;
        }
        public void DeleteSpecificationAttributeOption(Guid id)
        {
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IRepository<SpecificationAttributeOptionEntity> repo = IocContainer.Container().Resolve<IRepository<SpecificationAttributeOptionEntity>>();
                var result = repo.GetById(id);
                repo.Delete(result);
                if (commitTrans)
                    uow.TransactionalFlush();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error delete Specification Attribute item. ErrMsg: " + ex.Message, ex);
            }
        }

        public IList<related_product> GetRelatedProducts(Guid productId)
        {
            IList<related_product> data = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();
                var result = repo.GetRelatedProducts(productId);
                if (result != null)
                    data = (from c in result orderby c.DisplayOrder ascending select c.ToDataAdapter()).ToList();
            }
            catch (Exception ex)
            {
                throw new Exception("Get Related Products by ID Error::" + ex.Message, ex);
            }

            return data;
        }

        public void AddRelatedProduct(related_product item)
        {
             #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }           
            try
            {
                ProductEntity data = null, relatedProduct = null;
                IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();
                IRepository<RelatedProductEntity> repoPT = IocContainer.Container().Resolve<IRepository<RelatedProductEntity>>();

                data = repo.GetById(item.product1.id);
                relatedProduct = repo.GetById(item.product2.id);
                RelatedProductEntity related = new RelatedProductEntity
                {
                    DisplayOrder = item.display_order,
                    Product1 = data,
                    Product2 = relatedProduct
                };
                repoPT.SaveOrUpdate(related);
                if (commitTrans)
                    uow.TransactionalFlush();

            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error saving RelatedProduct data. ErrMsg: " + ex.Message, ex);
            }
        }

        public void RemoveRelatedProduct(Guid id)
        {

            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }
            try
            {              
                IRepository<RelatedProductEntity> repoPT = IocContainer.Container().Resolve<IRepository<RelatedProductEntity>>();
                RelatedProductEntity data = repoPT.GetById(id);
                if (data != null)
                {
                    repoPT.Delete(data);
                }
                if (commitTrans)
                    uow.TransactionalFlush();

            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error delete RelatedProduct data. ErrMsg: " + ex.Message, ex);
            }
        }

        public IList<product> SearchProduct(string keyword, Guid categoryId)
        {

            IList<product> data = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();
                var result = repo.SearchProduct(keyword, categoryId);
                if (result != null)
                    data = (from c in result orderby c.ModifiedDate descending select c.ToDataAdapter()).ToList();
            }
            catch (Exception ex)
            {
                throw new Exception("Get Search Product by ID Error::" + ex.Message, ex);
            }

            return data;
        }

        public IList<product_variant_attribute> GetProductVariantAttribute(Guid productVariantId)
        {
            IList<product_variant_attribute> data = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();
                var result = repo.GetProductVariantAttribute(productVariantId);
                if (result != null)
                    data = (from c in result orderby c.DisplayOrder ascending select c.ToDataAdapter()).ToList();
            }
            catch (Exception ex)
            {
                throw new Exception("Get Product Variant Attributeby ID Error::" + ex.Message, ex);
            }

            return data;
        }
        public void DeleteProductVariantAttribute(Guid id)
        {
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IRepository<ProductVariantAttributeEntity> repo = IocContainer.Container().Resolve<IRepository<ProductVariantAttributeEntity>>();
                var result = repo.GetById(id);
                repo.Delete(result);
                if (commitTrans)
                    uow.TransactionalFlush();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error delete Product Variant Attribute item. ErrMsg: " + ex.Message, ex);
            }
        }
        public IList<product_variant_attribute_value> GetProductVariantAttributeValue(Guid productVariantAttributeId)
        {
            IList<product_variant_attribute_value> data = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                IProductDataRepository repo = IocContainer.Container().Resolve<IProductDataRepository>();
                var result = repo.GetProductVariantAttributeValue(productVariantAttributeId);
                if (result != null)
                    data = (from c in result orderby c.DisplayOrder ascending select c.ToDataAdapter()).ToList();
            }
            catch (Exception ex)
            {
                throw new Exception("Get Product Variant Attributeby ID Error::" + ex.Message, ex);
            }

            return data;
        }
        public void DeleteProductVariantAttributeValue(Guid id)
        {
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IRepository<ProductVariantAttributeValueEntity> repo = IocContainer.Container().Resolve<IRepository<ProductVariantAttributeValueEntity>>();
                var result = repo.GetById(id);
                repo.Delete(result);
                if (commitTrans)
                    uow.TransactionalFlush();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error delete Product Variant Attribute Value item. ErrMsg: " + ex.Message, ex);
            }
        }
        public IList< product_specification_attribute> GetSpecificationOptionAttributeForProduct(Guid id)
        {
            IList<product_specification_attribute> list = null;
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
           
            try
            {
                IProductDataRepository repoP = IocContainer.Container().Resolve<IProductDataRepository>();
                var data = repoP.GetSpecificationOptionAttributeForProduct(id);
                if (data != null)
                {
                    list = (from c in data orderby c.DisplayOrder ascending select c.ToDataAdapter()).ToList();
                }
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error GetSpecificationOptionAttributeForProduct data. ErrMsg: " + ex.Message, ex);
            }
            return list;
        }
        public void DeleteProductSpecificationAttribute(Guid id)
        {
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IRepository<ProductSpecificationAttributeEntity> repo = IocContainer.Container().Resolve<IRepository<ProductSpecificationAttributeEntity>>();
                var result = repo.GetById(id);
                repo.Delete(result);
                if (commitTrans)
                    uow.TransactionalFlush();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error delete Product Specification Attribute Value item. ErrMsg: " + ex.Message, ex);
            }
        }
        public product_specification_attribute GetProductSpecificationAttribute(Guid id)
        {
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            product_specification_attribute item = null;
            try
            {
                 IRepository<ProductSpecificationAttributeEntity> repoPA = IocContainer.Container().Resolve<IRepository<ProductSpecificationAttributeEntity>>();

                ProductSpecificationAttributeEntity data = repoPA.GetById(id);
                if (data != null)
                    item = data.ToDataAdapter();
              
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error GetProductSpecificationAttribute data. ErrMsg: " + ex.Message, ex);
            }
            return item;
        }
        public void DeleteCategoryMapToProduct(Guid id)
        {
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IRepository<ProductCategoryEntity> repo = IocContainer.Container().Resolve<IRepository<ProductCategoryEntity>>();
                var result = repo.GetById(id);
                repo.Delete(result);
                if (commitTrans)
                    uow.TransactionalFlush();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error Delete CategoryMap To Product. ErrMsg: " + ex.Message, ex);
            }
        }
        public void DeletePictureMapToProduct(Guid id)
        {
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IRepository<PictureEntity> repo = IocContainer.Container().Resolve<IRepository<PictureEntity>>();
                var result = repo.GetById(id);
                repo.Delete(result);
                if (commitTrans)
                    uow.TransactionalFlush();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error Delete Picture To Product. ErrMsg: " + ex.Message, ex);
            }
        }
        public product_category GetCategoryById(Guid id)
        {
            product_category data = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                IRepository<CategoryEntity> repo = IocContainer.Container().Resolve<IRepository<CategoryEntity>>();

                var d = repo.GetById(id);
                if (d != null)
                    data = d.ToDataAdapter();
            }
            catch (Exception ex)
            {
                throw new Exception("Get GetCategoryById by ID Error::" + ex.Message, ex);
            }

            return data;
        }
        public void DeleteCategory(Guid id)
        {
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                IRepository<CategoryEntity> repo = IocContainer.Container().Resolve<IRepository<CategoryEntity>>();
                var result = repo.GetById(id);
                repo.Delete(result);
                if (commitTrans)
                    uow.TransactionalFlush();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error delete category item. ErrMsg: " + ex.Message, ex);
            }
        }
    }
}
